package com.mjgy.controller;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpSession;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.common.utils.PageUtils;
import com.common.utils.Query;
import com.common.utils.R;
import com.mjgy.entity.AlbumUnlocker;
import com.mjgy.entity.ContactWayWhiteList;
import com.mjgy.entity.MUserEntity;
import com.mjgy.entity.UserReportEntity;
import com.mjgy.repository.AlbumUnlockerRepository;
import com.mjgy.repository.CheckWhiteListRepository;
import com.mjgy.repository.ContactWayWhiteListRepository;
import com.mjgy.repository.MUserRepository;
import com.mjgy.repository.UserReportRepository;
import com.mjgy.service.MUserService;
import com.mjgy.service.TokenService;
import com.mjgy.service.UserReportService;
import com.mjgy.utils.Const;

import net.sf.json.JSONObject;

/**
* @Description: 用户相关接口
* @author LGC
* @date 2018年7月11日
* @version V1.0
*/
@RestController
@RequestMapping("/user")
public class MUserController {
	
	private Logger logger = Logger.getLogger(getClass());
	
	@Autowired
	private MUserService mUserService;
	@Autowired
	private TokenService tokenService;
	@Autowired
	private CheckWhiteListRepository checkWhiteListRepository;
	@Autowired
	private AlbumUnlockerRepository albumUnlockerRepository;
	@Autowired
	private ContactWayWhiteListRepository contactWayWhiteListRepository;
	@Autowired
	private MUserRepository mUserRepository;
	@Autowired
	private UserReportRepository userReportRepository;
	@Autowired
	private UserReportService userReportService;
	
	/**
	 * 注册
	 * 
	 * @param username
	 * @param password
	 * @param deviceCode
	 * @param sex
	 * @return
	 */
	@RequestMapping("/register")
	public R register(HttpSession session, String username, String password, String verifCode, int sex, String applyCodeInfo) {
		// 校验验证码
		String sessVerifCode = (String) session.getAttribute(username);
		// 没有验证码，直接退出
		if(sessVerifCode == null) {
			return R.error(202, "验证码不能为空");
		}
		
		// 验证码不匹配
		if(!sessVerifCode.equals(verifCode)) {
			return R.error(203, "验证码不匹配");
		}
		
		Date d = (Date) session.getAttribute(username + "Time");
		Date now = new Date();
		long second = now.getTime() - d.getTime();
		// 验证码过时
		if(second > Const.VERFICODETIME.longValue()) {
			// 移除验证码
			session.removeAttribute(username);
			session.removeAttribute(username + "Time");
			return R.error(204, "验证码过期");
		}
		
		session.removeAttribute(username);
		session.removeAttribute(username + "Time");
		R r = mUserService.register(username, password, sex, applyCodeInfo);
		if(202 == (Integer) r.get("code")){
			return r;
		}
		JSONObject data = (JSONObject) r.get("data");
		Long userId = (Integer) data.get("userId") + 0L;
		String token = tokenService.saveOrUpdateToken(userId);
		JSONObject jo = new JSONObject();
		jo.put("token", token);
		jo.put("id", userId);
		jo.put("sex", sex);
		
		return R.success().put("data", jo);
	}
	
	/**
	 * 更新用户性别
	 * 
	 * @param userId
	 * @param sex
	 * @return
	 */
	@RequestMapping("/updateUserSex")
	public R updateUserSex(Long userId, int sex) {
		return mUserService.updateUserSex(userId, sex);
	}
	
	/**
	 * 忘记密码
	 * 
	 * @param phone
	 * @param verifCode
	 * @param newPassword
	 * @return
	 */
	@RequestMapping("/forgetPassword")
	public R forgetPassword(HttpSession session, String phone, String verifCode, String newPassword) {
		// 校验验证码
		String sessVerifCode = (String) session.getAttribute(phone);
		// 没有验证码，直接退出
		if(sessVerifCode == null) {
			return R.error(202, "验证码不能为空");
		}
		
		// 验证码不匹配
		if(!sessVerifCode.equals(verifCode)) {
			return R.error(203, "验证码不匹配");
		}
		
		Date d = (Date) session.getAttribute(phone + "Time");
		Date now = new Date();
		long second = now.getTime() - d.getTime();
		// 验证码过时
		if(second > Const.VERFICODETIME.longValue()) {
			// 移除验证码
			session.removeAttribute(phone);
			session.removeAttribute(phone + "Time");
			return R.error(204, "验证码过期");
		}
		
		session.removeAttribute(phone);
		session.removeAttribute(phone + "Time");
		return mUserService.forgetPassword(phone, newPassword);
	}
	
	/**
	 * 登录
	 * 
	 * @param username
	 * @param password
	 * @param deviceCode
	 * @return
	 */
	@RequestMapping("/login")
	public R login(String username, String password, String deviceCode) {
		R r = mUserService.login(username, password, deviceCode);
		if("200".equals(r.get("code").toString())) {
			MUserEntity user = (MUserEntity) r.get("data");
			String token = tokenService.saveOrUpdateToken(user.getId());
			JSONObject jo = new JSONObject();
			jo.put("token", token);
			jo.put("id", user.getId());
			jo.put("sex", user.getSex());
			jo.put("identity", user.getIdentity());
			jo.put("nickname", user.getNickname() == null ? "" : user.getNickname());
			
			return r.put("data", jo);
		}
		
		return r;
	}
	
	/**
	 * 上传头像
	 * 
	 * @param userId
	 * @param imagePath
	 * @return
	 */
	@RequestMapping("/uploadAvatar")
	public R uploadAvatar(Long userId, String imagePath) {
		return mUserService.uploadAvatar(userId, imagePath);
	}
	
	/**
	 * 更改用户信息
	 * 
	 * @param params
	 * @return
	 */
	@RequestMapping("/updateUserInfo")
	public R updateUserInfo(MUserEntity user) {
		return mUserService.updateUserInfo(user);
	}
	
	/**
	 * 绑定手机号码
	 * 
	 * @param userId
	 * @param phone
	 * @param verifCode
	 * @return
	 */
	@RequestMapping("/bindPhone")
	public R bindPhone(HttpSession session, Long userId, String phone, String verifCode) {
		// 校验验证码
		String sessVerifCode = (String) session.getAttribute(phone);
		// 没有验证码，直接退出
		if(sessVerifCode == null) {
			return R.error(202, "验证码不能为空");
		}
		
		// 验证码不匹配
		if(!sessVerifCode.equals(verifCode)) {
			return R.error(203, "验证码不匹配");
		}
		
		Date d = (Date) session.getAttribute(phone + "Time");
		Date now = new Date();
		long second = now.getTime() - d.getTime();
		// 验证码过时
		if(second > Const.VERFICODETIME.longValue()) {
			// 移除验证码
			session.removeAttribute(phone);
			session.removeAttribute(phone + "Time");
			return R.error(204, "验证码过期");
		}
		
		session.removeAttribute(phone);
		session.removeAttribute(phone + "Time");
		return mUserService.bindPhone(userId, phone);
	}
	
	/**
	 * 更新用户密码
	 * 
	 * @param userId
	 * @param oldPassword
	 * @param newPassword
	 * @return
	 */
	@RequestMapping("/updatePassword")
	public R updatePwd(Long userId, String oldPassword, String newPassword) {
		return mUserService.updatePwd(userId, oldPassword, newPassword);
	}
	
	/**
	 * 获取本省市内的所有用户信息
	 * 
	 * @param province
	 * @param city
	 * @param sex 分男性列表和女性列表
	 * @param type 1:热门，2：新来，3：认证
	 * @param page
	 * @param pageSize
	 * @return
	 */
	@RequestMapping("/getAllUserInfo")
	public R getAllUserInfo(Long userId, String province, String city, int sex, int type, Integer page, Integer pageSize) {
		return mUserService.getAllUserInfo(userId, province, city, sex, type, page, pageSize);
	}
	
	/**
	 * 获取附近的人
	 * 
	 * @param userId
	 * @param lon
	 * @param lat
	 * @return
	 */
	@RequestMapping("/getNearbyUserInfo")
	public R getNearbyUserInfo(Long userId, BigDecimal lon, BigDecimal lat) {
		return mUserService.getNearbyUserInfo(userId, lon, lat);
	}
	
	/**
	 * 搜索
	 * 
	 * @param nickname 昵称（模糊查询）
	 * @param age 年龄（范围值）
	 * @param height 身高（范围值）
	 * @param weight 体重（范围值）
	 * @param cupSize 罩杯（固定值）
	 * @param occupation 职业（固定值）
	 * @param style 打扮风格（固定值）
	 * @param language 语言（固定值）
	 * @param relationship 情感（固定值）
	 * @param dationProgram 约会节目（多选）
	 * @param datingCodition 约会条件（多选）
	 * @return
	 */
	@RequestMapping("/searchUserInfo")
	public R searchUserInfo(String nickname, String age, String height, String weight, String cupSize, 
			String occupation, String style, String language, String relationship, String dationProgram, String datingCodition) {
		return mUserService.searchUserInfo(nickname, age, height, weight, cupSize, occupation, style, language, relationship, dationProgram, datingCodition);
	}
	
	/**
	 * 获取用户个人信息
	 * 
	 * @param userId
	 * @return
	 */
	@RequestMapping("/getUserInfo")
	public R getUserInfo(Long userId, Long viewerId) {
		return mUserService.getUserInfo(userId, viewerId);
	}
	
	/**
	 * 更新用户位置信息
	 * 
	 * @param userId
	 * @param lon
	 * @param lat
	 * @return
	 */
	@RequestMapping("/updateUserLocation")
	public R updateUserLocation(Long userId, double lon, double lat) {
		return mUserService.updateUserLocation(userId, lon, lat);
	}
	
	/**
	 * 是否拥有查看权限
	 * @param userId	被查看人ID
	 * @param checkerId	查看人ID
	 * @return
	 */
	@RequestMapping("/hasCheckPermission")
	public R hasCheckPermission(Long userId, Long checkerId){
		Integer count = checkWhiteListRepository.countByUserIdAndCheckerId(userId, checkerId);
		return R.success().put("hasCheckPermission", count > 0);
	}
	
	/**
	 * 更新用户的查看权限
	 * 
	 * @param userId	用户ID
	 * @param checkLimit	查看权限：0=公开，1=查看相册付费，2=查看前需要通过我的验证，3=隐身
	 * @return
	 */
	@RequestMapping("/updateCheckLimit")
	public R updateCheckLimit(Long userId, Integer checkLimit) {
		return mUserService.updateCheckLimit(userId, checkLimit);
	}
	
	/**
	 * 设置付费相册金额
	 * 
	 * @param userId	用户ID
	 * @param albumAmount	付费相册设置金额
	 * @return
	 */
	@RequestMapping("/updateAlbumAmount")
	public R updateAlbumAmount(Long userId, BigDecimal albumAmount) {
		if(userId == null){
			return R.error(202, "用户ID不能为空");
		}
		if(albumAmount == null){
			return R.error(202, "付费相册设置金额不能为空");
		}
		if(albumAmount.compareTo(BigDecimal.ZERO) < 0 || albumAmount.compareTo(new BigDecimal(100.00)) > 0){
			return R.error(202, "付费相册设置金额必须大于0，小于等于100");
		}
		return mUserService.updateAlbumAmount(userId, albumAmount);
	}
	
	/**
	 * 是否拥有查看付费相册的权限
	 * @param userId	用户ID
	 * @param unlockerId	解锁人ID
	 * @return
	 */
	@RequestMapping("/hasAlbumPermission")
	public R hasAlbumPermission(Long userId, Long unlockerId){
		Integer count = albumUnlockerRepository.countByUserIdAndUnlockerId(userId, unlockerId);
		return R.success().put("hasAlbumPermission", count > 0);
	}
	
	/**
	 * 是否拥有查看联系方式的权限
	 * @param userId	用户ID
	 * @param checkerId	查看联系方式的人ID
	 * @return
	 */
	@RequestMapping("/hasContactWayPermission")
	public R hasContactWayPermission(Long userId, Long checkerId){
		if(userId == null){
			return R.error(202, "被查看联系方式的人ID不能为空");
		}
		if(checkerId == null){
			return R.error(202, "查看联系方式的人ID不能为空");
		}
		Integer count = contactWayWhiteListRepository.countByUserIdAndCheckerIdAndType(userId, checkerId, 0);
		if(count > 0){
			return R.success().put("hasContactWayPermission", count > 0);
		}
		MUserEntity mUserEntity = mUserRepository.findTopById(checkerId);
		if(mUserEntity.getIdentity() == 1){
			count = contactWayWhiteListRepository.countByUserIdAndCheckerIdAndType(userId, checkerId, 1);
			if(count > 0){
				return R.success().put("hasContactWayPermission", true);
			}
		}
		return R.success().put("hasContactWayPermission", false);
	}
	
	/**
	 * 会员免费查看联系方式统计
	 * @param checkerId 查看人的ID
	 * @return
	 */
	@RequestMapping("/checkContactWayNum")
	public R checkContactWayNum(Long checkerId){
		if(checkerId == null){
			return R.error(202, "查看人的ID不能空");
		}
		Integer count = contactWayWhiteListRepository.countByCheckerIdAndType(checkerId, 1);	//会员免费查看统计
		return R.success().put("checkContactWayNum", count);
	}
	
	/**
	 * 查看联系方式标记
	 * @param contactWayWhiteList 联系方式白名单
	 * @return
	 */
	@RequestMapping(value = "/signContactWay", method = RequestMethod.POST)
	public R signContactWay(ContactWayWhiteList contactWayWhiteList){
		if(contactWayWhiteList == null){
			return R.error(202, "入参不能为空");
		}
		if(contactWayWhiteList.getUserId() == null){
			return R.error(202, "用户ID不能为空");
		}
		if(contactWayWhiteList.getCheckerId() == null){
			return R.error(202, "查看联系方式的人ID不能为空");
		}
		MUserEntity mUserEntity = mUserRepository.findTopById(contactWayWhiteList.getCheckerId());
		if(mUserEntity.getIdentity() != 1){
			return R.error(202, "非会员需要付费查看联系方式，不适用本接口");
		}
		
		Integer count = contactWayWhiteListRepository.countByUserIdAndCheckerIdAndType(contactWayWhiteList.getUserId(), 
				contactWayWhiteList.getCheckerId(), 1);
		if(count > 0){
			return R.error(202, "该联系方式已标记，请勿重复标记");
		}
		count = contactWayWhiteListRepository.countByCheckerIdAndType(contactWayWhiteList.getCheckerId(), 1);
		if(count >= 3){
			return R.error(202, "已超过免费查看次数，不适用本接口");
		}
		contactWayWhiteList.setType(1);	//会员免费查看3个女士联系方式
		contactWayWhiteList.setCreateTime(new Date());
		
		contactWayWhiteListRepository.save(contactWayWhiteList);
				
		return R.success();
	}
	
	/**
	 * 会员免费查看付费相册次数统计
	 * @param unlockerId 解锁人的ID
	 * @return
	 */
	@RequestMapping("/checkAlbumNum")
	public R checkAlbumNum(Long unlockerId){
		if(unlockerId == null){
			return R.error(202, "解锁人的ID不能空");
		}
		Integer count = albumUnlockerRepository.countByUnlockerIdAndType(unlockerId, 1);	//会员免费查看付费相册统计
		return R.success().put("checkAlbumNum", count);
	}
	
	/**
	 * 付费相册解锁标记
	 * @param albumUnlocker	付费相册解锁中间表
	 * @return
	 */
	@RequestMapping(value = "/signAlbum", method = RequestMethod.POST)
	public R signAlbum(AlbumUnlocker albumUnlocker){
		if(albumUnlocker == null){
			return R.error(202, "入参不能为空");
		}
		if(albumUnlocker.getUnlockerId() == null){
			return R.error(202, "解锁付费相册的人ID不能为空");
		}
		if(albumUnlocker.getUserId() == null){
			return R.error(202, "被解锁付费相册的人ID不能为 空");
		}
		
		Integer count = albumUnlockerRepository.countByUserIdAndUnlockerId(albumUnlocker.getUnlockerId(), albumUnlocker.getUserId());
		if(count > 0){
			return R.error(202, "该付费相册已标记，请勿重复标记");
		}
		Integer freeCount = albumUnlockerRepository.countByUnlockerIdAndType(albumUnlocker.getUnlockerId(), 1);
		if(freeCount >= 3){
			return R.error(202, "已超过免费查看次数，不适用本接口");
		}
		
		albumUnlocker.setType(1);
		albumUnlocker.setCreateTime(new Date());
		albumUnlockerRepository.save(albumUnlocker);
		
		return R.success();
	}
	
	/**
	 * 女性认证
	 * 
	 * @param userId
	 * @param identityPhoto
	 * @return
	 */
	@RequestMapping("/identity")
	public R identity(Long userId, String identityPhoto) {
		return mUserService.identity(userId, identityPhoto);
	}
	
	/**
	 * 用户举报
	 * @param userReportEntity 用户举报实体
	 * @return
	 */
	@RequestMapping("/report")
	public R report(UserReportEntity userReportEntity){
		if(userReportEntity == null){
			return R.error(202, "入参不能为空");
		}
		if(userReportEntity.getActiveId() == null){
			return R.error(202, "举报人ID不能为空");
		}
		if(userReportEntity.getPassiveId() == null){
			return R.error(202, "被举报人ID不能为空");
		}
		
		userReportEntity.setCreateTime(new Date());
		userReportRepository.save(userReportEntity);
		
		return R.success();
	}
	
	
	//------------------------------后台管理--------------------------------------//
	
	/**
	 * 用户列表
	 * 
	 * @param params
	 * @return
	 */
	@RequestMapping("/list")
	public R list(@RequestParam Map<String, Object> params) {
		// 查询列表数据
		Query query = new Query(params);
		PageUtils pageUtil = mUserService.queryPage(query);	
		return R.ok().put("page", pageUtil);
	}
	
	/**
	 * 设备码列表
	 * 
	 * @param params
	 * @return
	 */
	@RequestMapping("/deviceCodeList")
	public R deviceCodeList(@RequestParam Map<String, Object> params) {
		Query query = new Query(params);
		PageUtils pageUtil = mUserService.queryDeviceCodePage(query);
		return R.ok().put("page", pageUtil);
	}
	
	/**
	 * 封禁/解封设备
	 * 
	 * @param id
	 * @return
	 */
	@RequestMapping(value = "/editDeviceCode/{id}/{status}")
	public R editDeviceCode(@PathVariable Long id, @PathVariable boolean status) {
		return mUserService.editDeviceCode(id, status);
	}
	
	/**
	 * 认证列表
	 * 
	 * @param params
	 * @return
	 */
	@RequestMapping("/identityList")
	public R identityList(@RequestParam Map<String, Object> params) {
		Query query = new Query(params);
		PageUtils pageUtil = mUserService.queryIdentityPage(query);
		return R.ok().put("page", pageUtil);
	}
	
	/**
	 * 是否通过认证
	 * 
	 * @param id
	 * @param identity
	 * @return
	 */
	@RequestMapping("/editIdentity/{id}/{identity}")
	public R editIdentity(@PathVariable Long id, @PathVariable int identity) {
		return mUserService.editIdentity(id, identity);
	}
	
	/**
	 * 用户详情
	 * 
	 * @param id
	 * @return
	 */
	@RequestMapping("/userDetail/{id}")
	public R userDetail(@PathVariable Long id) {
		return mUserService.userDetail(id);
	}

	/** 查找用户举报列表
	 * @param sex	性别
	 * @param city	城市
	 * @param identity	身份
	 * @param nickname	昵称
	 * @param page	页码
	 * @param size	每页条数
	 * @return
	 */
	@RequestMapping("/findUserReportList")
	public R findUserReportList(Integer sex, String city, Integer identity, String nickname, Integer page, Integer size){
		if(sex == null){
			return R.error(202, "性别不能为空");
		}
		if(page == null){
			page = 1;
		}
		if(size == null){
			size = 20;
		}
		if(city == null){
			city = "";
		}
		if(nickname == null){
			nickname = "";
		}
		List<Map<String, Object>> list = userReportService.findListBySex(sex, city, identity, nickname, page, size);
		Long totalCount = userReportService.countBySex(sex, city, identity, nickname);
		Long totalPage = totalCount / size + (totalCount % size == 0?0:1);
		
		Map<String, Object> data = new HashMap<>();
		data.put("list", list);
		data.put("currPage", page);
		data.put("pageSize", size);
		data.put("totalCount", totalCount);
		data.put("totalPage", totalPage);
		return R.success().put("data", data);
	}
	
	@RequestMapping("/userDel/{id}")
	public R userDel(@PathVariable Long id) {
		return mUserService.userDel(id);
	}
	
	@RequestMapping("/userFreezeOrThaw")
	public R userFreezeOrThaw(@RequestParam Map<String, Object> params) {
		return mUserService.userFreezeOrThaw(params);
	}
	
	@RequestMapping("/userAvatarFreeze/{id}")
	public R userAvatarFreeze(@PathVariable Long id) {
		return mUserService.userAvatarFreeze(id);
	}
}
